package core

import (
	"github.com/shopspring/decimal"
)

func getGroupIdMap(mp map[string]string, str string, key string) {
	//if str[0] == '$' {
	if key != "" {
		mp[key] = str[1:]
	} else {
		mp[str[1:]] = str[1:]
	}
	//} else {
	//	if key != "" {
	//		mp[key] = str
	//	} else {
	//		mp[str] = str
	//	}
	//}
}

func Group(source []map[string]interface{}, _group map[string]interface{}) []map[string]interface{} {
	//第一遍确定顺序
	//是否使用联合主键
	multi := false
	var multiId = map[string]string{}
	var fields = map[string]map[string]interface{}{}
	for k, v := range _group {
		if k == "_id" {
			if v == nil {
				multiId["_id"] = "_id"
				continue
			}
			switch v.(type) {
			case string:
				str := v.(string)
				getGroupIdMap(multiId, str, "")
				break
			case []interface{}:
				multi = true
				arr := v.([]interface{})
				for _, v := range arr {
					if str, ok := v.(string); ok {
						getGroupIdMap(multiId, str, "")
					}
				}
				break
			case map[string]interface{}:
				multi = true
				mp := v.(map[string]interface{})
				for k, v := range mp {
					if str, ok := v.(string); ok {
						getGroupIdMap(multiId, str, k)
					}
				}
				break
			}
		} else {
			switch v.(type) {
			case map[string]interface{}:
				fields[k] = v.(map[string]interface{})
				break
			}
		}

	}

	var nRet = []map[string]interface{}{}
	//if multi {
	var cache = map[string][]map[string]interface{}{}
	for _, v := range source {
		//var item = map[string]interface{}{}
		//基本字段
		var _id string
		for _, vv := range multiId {
			_id += "$" + toString(v[vv])
		}
		cache[_id] = append(cache[_id], v)
	}
	//分组统计
	for _, singleGroup := range cache {
		var mp = map[string]interface{}{}
		//放入_id
		if multi {
			var _id = map[string]interface{}{}
			for kk, vv := range multiId {
				_id[kk] = singleGroup[0][vv]
			}
			mp["_id"] = _id
		} else {
			for kk, vv := range multiId {
				mp[kk] = singleGroup[0][vv]
			}
		}
		//放入额外的统计字段
		for k, v := range fields {
			addGroupField(mp, singleGroup, k, v)
		}
		nRet = append(nRet, mp)
	}
	//} else {

	//}

	return nRet
}

func toString(value interface{}) string {
	if value == nil {
		return ""
	}
	switch value.(type) {
	//如果新插入的和log中读取的并存，那么需要先统一格式
	case decimal.Decimal:
		return value.(decimal.Decimal).String()
	case string:
		return value.(string)
	default:
		return ""
	}
}

func handleSum(group []map[string]interface{}, v interface{}) decimal.Decimal {
	var total = decimal.NewFromInt(0) //float64(0)
	switch v.(type) {
	case decimal.Decimal:
		for _ = range group {
			total = total.Add(v.(decimal.Decimal))
		}
		break

	case string:
		//如果是字符串，那么取值
		var str = v.(string)
		for _, item := range group {
			sumSupport(&total, item[str[1:]])
		}
		break
	}
	return total
}

func handleAvg(group []map[string]interface{}, v interface{}) decimal.Decimal {
	var total = handleSum(group, v)
	return total.Div(decimal.NewFromInt(int64(len(group))))
}

func addGroupField(mp map[string]interface{}, group []map[string]interface{}, key string, value map[string]interface{}) {
	for k, v := range value {
		switch k {
		case "$sum":
			v, _ := handleSum(group, v).Float64()
			mp[key] = v
			break
		case "$avg":
			v, _ := handleAvg(group, v).Float64()
			mp[key] = v
		}
	}
}

func sumSupport(left *decimal.Decimal, right interface{}) {
	switch right.(type) {
	case decimal.Decimal:
		*left = left.Add(right.(decimal.Decimal))
		break
	}
}
